package embeded.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.RemoteException;
import java.util.Properties;

import javax.rmi.PortableRemoteObject;

import org.omg.CORBA.ORB;
import org.omg.PortableServer.POA;

import client.RemoteParticipant;
import client._ParticipantUser_Stub;
import client._RemoteParticipant_Stub;
import client.impl.RemoteParticipantImpl;
import client.impl._RemoteParticipantImpl_Tie;

import embeded.EmbededObject;
import embeded.Participant;
import embeded.ParticipantLisntener;

public class ParticipantLisntenerImpl extends Thread implements
		ParticipantLisntener {
	private EmbededObject embededObject = null;
	private int listening_port;
	private String listening_address;
	private ORB orb;
	private POA poa;

	public ParticipantLisntenerImpl(EmbededObject embededObject, ORB orb,
			POA poa) {
		this.embededObject = embededObject;
		this.orb = orb;
		this.poa = poa;
	}

	@Override
	public void run() {
		super.run();
		doListening();
	}

	private void doListening() {
		Socket broadcaster = null;
		String iorSender = null;
		loadProperties();
		try {
			// listenerBroadcast = new ServerSocket(listening_port);
			embededObject.getTextfield().append(
					"ParticipantListener : listening sussesfull\n");
			MulticastSocket sender = new MulticastSocket(listening_port);
			InetAddress group = InetAddress.getByName(listening_address);
			sender.joinGroup(group);
			byte[] byteIor;
			boolean isConnect = false;
			while (true) {
				byteIor = new byte[1024];
				DatagramPacket reader = new DatagramPacket(byteIor,
						byteIor.length);
				sender.receive(reader);
				iorSender = new String(byteIor).trim();
		//		System.out.println(iorSender);

				try {
					broadcaster = new Socket(reader.getAddress(),
							listening_port);
					isConnect = true;
				} catch (Exception e) {
					isConnect = false;
				}
				if (isConnect) {
					PrintWriter pred = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(
									broadcaster.getOutputStream())), true);

					org.omg.CORBA.Object objet = orb
							.string_to_object(iorSender);

					_ParticipantUser_Stub participantUser = (_ParticipantUser_Stub) PortableRemoteObject
							.narrow(objet, _ParticipantUser_Stub.class);

					if (participantUser != null) {
						Participant localPariticipantUser = embededObject
								.addParticipant(participantUser
										.getParticipantName());
						if (localPariticipantUser == null)
							pred.println("null");
						else {
							RemoteParticipant remote = new RemoteParticipantImpl(
									localPariticipantUser, orb, embededObject);
							remote.setParticipantUser(participantUser);
							_RemoteParticipantImpl_Tie tie = new _RemoteParticipantImpl_Tie();
							tie.setTarget(remote);
							try {
								org.omg.CORBA.Object obj = this.poa
										.servant_to_reference(tie);
								iorSender = orb.object_to_string(obj);
								pred.println(iorSender);

							} catch (Exception e) {

								e.printStackTrace();
							}
						}
					}
					pred.close();
				}
			}
		} catch (IOException e) {
			try {
				embededObject.getTextfield().append(
						"ParticipantListener : error listening\n");
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}

	private boolean loadProperties() {
		Properties prop = new Properties();
		String path = new File(".").getAbsolutePath();
		path = path.substring(0, path.length() - 1);
		try {
			prop.load(new FileInputStream(path + "conf\\properties.properties"));
			listening_port = Integer.parseInt(prop
					.getProperty("PARTICIPANT_LISTENING_PORT"));
			listening_address = prop
					.getProperty("PARTICIPANT_LISTENING_ADDRESS");
		} catch (Exception e) {
			try {
				embededObject
						.getTextfield()
						.append("ParticipantListener : Error getting properties from file\n");
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public void startListening() {
		this.start();
	}

	public void stopListening() {
		this.stop();
	}

}
